package org.celstec.mobilegame.locatory;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import javax.jdo.PersistenceManager;
import javax.jdo.annotations.ForeignKey;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.NotPersistent;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.servlet.http.HttpServletRequest;

import org.celstec.mobilegame.gamaray.Asset;
import org.celstec.mobilegame.gamaray.Dimension;
import org.celstec.mobilegame.gamaray.OverlayImg;
import org.celstec.mobilegame.gamaray.OverlayTxt;
import org.celstec.mobilegame.server.PMF;
import org.celstec.mobilegame.server.SubmitGameServiceImpl;
import org.celstec.mobilegame.util.GPSUtil;

import com.google.appengine.api.datastore.Key;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class LocatoryPlay {

	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	public Key key;

	@Persistent(defaultFetchGroup="true")
	public Key locatoryGame;

	public Key getLocatoryGame() {
		return locatoryGame;
	}

	public void setLocatoryGame(Key locatoryGame) {
		this.locatoryGame = locatoryGame;
	}

	@Persistent
	public String name;

	@Persistent(defaultFetchGroup = "true")
	@ForeignKey(table = "org.celstec.mobilegame.locatory.Card")
	public Set<Key> openCard = new HashSet();
	
	@NotPersistent
	private Locatory locatory;

	// private Vector<Card> openCards = new Vector<Card>();

	public static LocatoryPlay getObjectByName(String name) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			String query = "select from " + LocatoryPlay.class.getName()
					+ " where name =='" + name + "'";
			List<LocatoryPlay> plays = (List<LocatoryPlay>) pm.newQuery(query)
					.execute();
			if (plays.size() != 0) {
				return plays.get(0);
			}
			return null;
		} finally {
			pm.close();
		}
	}
	
	public void initNotPersistentObjects(PersistenceManager pm){
		if (openCard == null) openCard = new HashSet();
		locatory = (Locatory) pm.getObjectById(Locatory.class, getLocatoryGame());
	}

//	private HashMap<User, CardLocation> previousClicks = new HashMap<User, CardLocation>();

	public Set<Key> getCards() {
		return openCard;
	}

	public void setCards(Set<Key> cards) {
		this.openCard = cards;
	}

	public void addCard(Card card) {
		this.openCard.add(card.key);
	}

	public void removeCard(Card card) {
		this.openCard.remove(card.key);
	}

	public LocatoryPlay() {
	}

	public Locatory getLocatory() {
		if (locatory != null) return locatory;
		return Locatory.getObject(getLocatoryGame());
	}

	public LocatoryPlay(Locatory l, String name) {
		this.locatoryGame = l.key;
		// this.locatory = l;
		this.name = name;
		initOpenCards();
	}

	public void initOpenCards() {
		Iterator<Key> l = getLocatory().keysLocations.iterator();
		while (l.hasNext()) {
			Key key = (Key) l.next();
			CardLocation loc = CardLocation.getObject(key);
			Card c = Card.getObject(loc.getCard());// SubmitGameServiceImpl.getCard(loc.card);
			if (!openCard.contains(c.key))
				addCard(c);
		}
	}

	public void takeCardInBag(Card c, User u) {
		u.addCardToBag(c);
		u.setPreviousClick(null);
		removeCard(c);
	}

	public Dimension getDimension(User u, HttpServletRequest req) {
		Dimension returnDimension = new Dimension(name, Dimension.baseUrl
				+ "locatory?p=" + name);
		Vector<Asset> defaultAssets = getLocatory().getDefaultAssets();
		returnDimension.add(defaultAssets);
		CardLocation tabooCard = null;

		int width = 480;
		int height = 294;
		try {
			width = Integer.parseInt(req.getParameter("width"));
			height = Integer.parseInt(req.getParameter("height"));
		} catch (Exception e) {

		}

		if (req.getParameter("cardLocationClick") != null) {
			CardLocation loc = getLocatory().getCardLocation(
					req.getParameter("cardLocationClick"));
			CardLocation pc = u.getPreviousClick();
			if (pc != null && !pc.id.toString().equals(loc.id.toString())  && pc.card.getId() == loc.card.getId()) {
				takeCardInBag(Card.getObject(loc.card), u);
			} else {
				returnDimension.add(loc.getAsset());
				returnDimension.add(loc.getFeature());
				tabooCard = loc;
//				returnDimension.tabooCard = tabooCard;
			}
//			previousClicks.put(u, loc);
			u.setPreviousClick(loc);
		} else if (req.getParameter("cardCollectedClick") != null) {
			String cardId = req.getParameter("cardCollectedClick");
			Card c = getLocatory().getCard(cardId);
			returnDimension.add(new Asset(c.cardImageType, c.cardImage,
					"asset_card_" + c.cardId));
			returnDimension.add(new OverlayImg("asset_card_" + c.cardId,
					((width / 2)), (height / 2), "CC", "&amp;cardDropClick="
							+ cardId, "fig_" + cardId));

			returnDimension.add(new Asset(getLocatory().buttonCloseType,
					getLocatory().buttonClose, "asset_close_button"));
			returnDimension.add(new OverlayImg("asset_close_button",
					((width / 2) - 170), (height / 2), "CC", "&amp;reset=true"
							+ cardId, "close_button_id"));

			returnDimension.add(new Asset(getLocatory().buttonDropType,
					getLocatory().buttonDrop, "asset_drop_button"));
			returnDimension.add(new OverlayImg("asset_drop_button",
					((width / 2) + 170), (height / 2), "CC",
					"&amp;cardDropClick=" + cardId, "drop_button_id"));
		} else if (req.getParameter("cardDropClick") != null) {
			String cardId = req.getParameter("cardDropClick");
			Card c = locatory.getCard(cardId);
			removeCardFromDisplay(u, cardId);
			CardDropOffZone dz = c.getCardDropOffZone(getLocatory().keysZones);
			if (GPSUtil.distance(u, dz, GPSUtil.METERS) < 30) {
				u.setScore(u.getScore()+1);
			} else {
				addCard(c);
				u.setPreviousClick(null);
				// openCards.add(c);
			}

		}

		// else if (req.getParameter("reset") != null) {
		// updateCardLocationsOnMap(u.state, u);
		//
		// u.state = null;
		// } else if (u.state != null){
		// if (u.pState != null && u.pState.equals(p)){
		// updateCardLocationsOnMap(u.state, u);
		// return u.state;
		// }
		//			
		// }

		setCardLocationsOnMap(tabooCard, returnDimension, u);
		setDropOffZones(returnDimension);
		setUserCards(u, returnDimension, height);
		setUserScore(u, returnDimension, req);
		// u.state = returnDimension;
		// u.pState = p;
		return returnDimension;
	}

	private void removeCardFromDisplay(User u, String cardId) {
			Iterator it = u.cardBagString.iterator();
			while (it.hasNext()) {
				String card = (String) it.next();
				if (card.equals(cardId))
					u.removeCardFromBag(card);
			}
	}

	private void setCardLocationsOnMap(CardLocation tabooCard, Dimension d,
			User u) {
		Iterator<Key> l = getLocatory().keysLocations.iterator();
		while (l.hasNext()) {
			Key key = (Key) l.next();
			CardLocation cl = CardLocation.getObject(key);
			Card c = Card.getObject(cl.card);
			if (openCard.contains(c.key)) {
				if (tabooCard ==null || !cl.id.toString().equals(tabooCard.id.toString()) 
						&& GPSUtil.distance(u, cl, GPSUtil.METERS) <= cl.onDistance) {

					d.add(getLocatory().getDefaultCardImageFeature(cl));
				}
			}

		}
		// for (int i = 0; i < locatory.locations.size(); i++) {
		// CardLocation cl = locatory.locations.get(i);
		// if (openCards.contains(cl.card)) {
		// if (cl != tabooCard
		// && GPSUtil.distance(u, cl, GPSUtil.METERS) <= cl.onDistance) {
		//
		// d.add(locatory.getDefaultCardImageFeature(cl));
		// }
		// }
		//
		// }
	}

//	public void updateCardLocationsOnMap(Dimension d, User u) {
//		d.removeCardFeatures();
//		setCardLocationsOnMap(d.tabooCard, d, u);
//	}

	private void setDropOffZones(Dimension d) {
		Iterator<Key> l = getLocatory().keysZones.iterator();
		while (l.hasNext()) {
			Key key = (Key) l.next();
			CardDropOffZone zone = CardDropOffZone.getObject(key);
			d.add(zone.getFeature());
		}
		// for (int i = 0; i < locatory.zones.size(); i++) {
		// CardDropOffZone zone = locatory.zones.get(i);
		// d.add(zone.getFeature());
		// }
	}

	public void setUserCards(User u, Dimension d, int height) {
//		Vector cardBag = (Vector) u.getItem("cardBag");
//		if (cardBag != null) {
//			for (int i = 0; i < cardBag.size(); i++) {
//				Card c = (Card) cardBag.get(i);
//				d.add(c.getOverlay(i, height));
//				d.add(c.getIconCardImageAsset());
//			}
//		}
		if (u.cardBagString==null) u.cardBagString = new HashSet();
		Iterator it = u.cardBagString.iterator();
		int i = 0;
		while (it.hasNext()) {
			String cString = (String) it.next();
			Card c = Card.getObject(cString);
			d.add(c.getOverlay(i++, height));
			d.add(c.getIconCardImageAsset());
				
		}
	}

	public void setUserScore(User u, Dimension d, HttpServletRequest req) {
		int width = 480;
		int height = 294;
		try {
			width = Integer.parseInt(req.getParameter("width"));
			height = Integer.parseInt(req.getParameter("height"));
		} catch (Exception e) {

		}
		int score = u.score;
		d.add(new OverlayImg("scoreClose", width - 10, 10, "TR", null,
				"scoreCloseOI"));
		d.add(new OverlayImg("scoreOpen", width - 12 - 8 - 10, 10, "TR", null,
				"scoreOpenOI"));
		d.add(new OverlayImg("scoreNumber_" + score, width - 8 - 10, 10, "TR",
				null, "scoreNumber_" + score + "OI"));
		// d.add(u.getOverlay());
	}

}
